﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using GeoCoderParser;
using GeoUtils;

namespace BuildRankerFeatureSetByNaiveGeocoder
{
    class Program
    {
        //Construct Geocoder ranker training corpus bu naive Geocoder rule based algorithm
        static void Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("BuildRankerFeatureSetByNaiveGeocoder [Geograph coder Data Path] [raw training corpus] [feature set file name]");
                Console.WriteLine("Use naive Geocoder to extract feature set for ranker training.");
                return;
            }

            GeoCoderParser.AddressParser parser = new GeoCoderParser.AddressParser();
            parser.Initialize(args[0]);
            parser.SetRunMode("NORM_RULE"); //only use naive ranker, not use machine learning ranker

            GeoCoderParser.GeoCoderResult geoCoderResult;
            GeocoderRankerFeatureGenerator.GeocoderRankerFeatureGenerator featureGenerator = new GeocoderRankerFeatureGenerator.GeocoderRankerFeatureGenerator();
            StreamReader sr = new StreamReader(args[1], Encoding.UTF8);
            StreamWriter sw = new StreamWriter(args[2], false, Encoding.UTF8);


            Dictionary<string, int> dict = new Dictionary<string, int>();
            int max_qid = 1;
            while (sr.EndOfStream == false)
            {
                //Training corpus format:
                //上海升凯新能源开发有限公司	baidu	Shanghai	31.2285	121.47	2

                string strLine = sr.ReadLine();
                string[] items = strLine.Split('\t');
                string strQuery = items[0];
                double fX = double.Parse(items[3]);
                double fY = double.Parse(items[4]);
                LatLong latlong = new LatLong(fX, fY);

                ViewPort viewPort = null;
                GeoEntity region = parser.FindRegion(latlong);
                if (region != null)
                {
                    viewPort = new ViewPort(region.BoundingRect, latlong);
                }

                //Parse given query
                geoCoderResult = parser.Parse(strQuery, viewPort);
                
                //Found some geo-entity chains candidates
                if (geoCoderResult.allCandGeoEntityChainList.Count > 0)
                {
                    if (dict.ContainsKey(strQuery) == false)
                    {
                        dict.Add(strQuery, max_qid);
                        max_qid++;
                    }
                    //Each feature set record format:
                    //2 qid:13 1:2 2:0 3:2 4:1 5:2 6:1 7:0
                    //relevance qid:n 1:a 2:b 3:c ...

                    HashSet<string> setFeatureSet = new HashSet<string>();
                    int pos = 0;
                    foreach (GeoEntityChain item in geoCoderResult.allCandGeoEntityChainList)
                    {
                        if (pos >= 5)
                        {
                            break;
                        }

                        string strFeatureSet;
                        strFeatureSet = GeocoderRankerFeatureGenerator.GeocoderRankerFeatureGenerator.Generate(geoCoderResult.tokenList, item, viewPort);
                        string strWhere = "";
                        foreach (GeoUtils.GeoEntity sub in item.geoEntityList)
                        {
                            strWhere += sub.Name;
                        }

                        if (setFeatureSet.Contains(strFeatureSet) == false)
                        {
                            setFeatureSet.Add(strFeatureSet);
                            sw.WriteLine("# {0} {1}", strQuery, strWhere);
                            sw.WriteLine("{0} qid:{1} {2}", pos, dict[strQuery], strFeatureSet);
                            pos++;
                        }
                    }
                }
            }

            sr.Close();
            sw.Close();

        }
    }
}
